chess960 in OCaml — Source Code

(* to compile: ocamlfind ocamlopt -o chess960 -package kw chess960.ml -linkpkg *)

open Kw
open Kwlist
open List

(* application *)

type piece = R | N | B | Q | K

let sublist_between a b = (takewhile ((<>) b)) & tl & (dropwhile ((<>) a))

let valid_bishops pos =
  length (sublist_between B B pos) mod 2 = 0

let valid_king pos =
  filter (fun p -> p = R || p = K) pos = [R; K; R]

let genpositions () =
  uniq (
    sort compare (
      filter (conjunction [valid_king; valid_bishops])
		    (permutations [R;N;B;Q;K;B;N;R])))

(* printing *)

let string_of_piece = function
  | R -> "R" | N -> "N" | B -> "B" | Q -> "Q" | K -> "K"

let string_of_position = (String.concat "") & map string_of_piece

let print = iter (print_endline & string_of_position)

(* invocation *)

let positions = genpositions ()

let _ =
  if Array.length Sys.argv = 1
  then print positions
  else begin
    Random.self_init ();
    print (choose (int_of_string Sys.argv.(1)) positions)
  end